/*
 * DebianNet.cs
 * 
 * Copyright © 2008 David Paleino <d.paleino@gmail.com>
 * 
 *   This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *   
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *   
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, see
 *   <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections;
using System.Reflection;
using CookComputing.XmlRpc;

namespace HanskaLabs.Pastebin
{
	/// <summary>
	/// Support for <a href="http://paste.debian.net">paste.debian.net</a>.
	/// </summary>
	public class DebianNet : IPastebin
	{
		private IDebianNet proxy;
		
		/*
		 * Main constructor
		 */
		public DebianNet() {
			proxy = XmlRpcProxyGen.Create<IDebianNet>();
		}
		
		/*
		 * Returned data struct
		 */
		[XmlRpcMissingMapping(MappingAction.Ignore)]
		public struct Data {
			/*
			 * The members are marked as "optional", but aren't really optional.
			 * The reason why they're marked so is simple: have a unique struct,
			 * instead of n (where n is the number of methods) structs.
			 */
			[XmlRpcMissingMapping(MappingAction.Error)] // compulsory
			public int rc;
			[XmlRpcMissingMapping(MappingAction.Error)] // compulsory
			public string statusmessage;
			
			public int id;
			public string digest; // SHA1 hex
			public string code;
			public string submitter;
			public string submitdate;
			public int expiredate; // docs say it's a string, author mailed
			public string[] langs;
		}
		
		/*
		 * IPastebin implementation
		 */
		public Hashtable AddPaste(string pastetext) {
			return AddPaste(pastetext, "anonymous");
		}
		public Hashtable AddPaste(string pastetext, string name) {
			return AddPaste(pastetext, name, 172800);
		}
		public Hashtable AddPaste(string pastetext, string name, int expire) {
			return AddPaste(pastetext, name, expire, "");
		}
		public Hashtable AddPaste(string pastetext, string name, int expire, string lang) {
			Data data;
			Hashtable ret = new Hashtable();
			
			try {
				data = proxy.addPaste(pastetext, name, expire, lang);
				foreach (FieldInfo field in typeof(Data).GetFields()) {
					if (field.GetValue(data) != null) {
						// manually filter unwanted fields, i.e. deriving just
						// from the reflection process
						if (field.Name != "expiredate") {
							ret.Add(field.Name, field.GetValue(data));
						}
					}
				}
//				ret.Add("rc", data.rc);
//				ret.Add("statusmessage", data.statusmessage);
//				ret.Add("id", data.id);
//				ret.Add("digest", data.digest);
			}
			catch (Exception ex) {
				Console.WriteLine(ex.Message);
			}
			return ret;
		}
		
		public Hashtable RemovePaste(int id) {
			/*
			 * Normally it *can't* be supported, otherwise the normal (l)user
			 * could also delete other (l)users' pastes... and it ain't good.
			 * It is frontend's duty, by keeping a database for instance, to
			 * record digests received by AddPaste().
			 */
			throw new NotSupportedException("The selected pastebin doesn't support deleting by ID.");
		}
		public Hashtable RemovePaste(string digest) {
			Data data;
			Hashtable ret = new Hashtable();
			
			try {
				data = proxy.deletePaste(digest);

				foreach (FieldInfo field in typeof(Data).GetFields()) {
					if (field.GetValue(data) != null) {
						// manually filter unwanted fields, i.e. deriving just
						// from the reflection process
						if (field.Name != "expiredate") {
							ret.Add(field.Name, field.GetValue(data));
						}
					}
				}
//				ret.Add("rc", data.rc);
//				ret.Add("statusmessage", data.statusmessage);
//				ret.Add("id", data.id);
			}
			catch (Exception ex) {
				Console.WriteLine(ex.Message);
			}
			return ret;
		}
		
		public Hashtable GetPaste(string id) {
			Data data;
			Hashtable ret = new Hashtable();

			try {
				data = proxy.getPaste(Convert.ToInt32(id));

				foreach (FieldInfo field in typeof(Data).GetFields()) {
					if (field.GetValue(data) != null) {
						// manually filter unwanted fields, i.e. deriving just
						// from the reflection process
						if (field.Name != "id") {
							ret.Add(field.Name, field.GetValue(data));
						}
					}
				}
			}
			catch (Exception ex) {
				Console.WriteLine(ex.Message);
			}
			return ret;
		}
		
		public string[] GetLanguages() {
			Data data;
			string[] ret = {};
			
			try {
				data = proxy.getLanguages();
				ret = data.langs;
			}
			catch (Exception ex) {
				Console.WriteLine(ex.Message);
			}
			return ret;
		}
	}
}
